package optimizers.ganeat.jankenpon;

import java.util.concurrent.Callable;

import fitness.EloRecord;
import fitness.EloRecord.Result;
import fitness.JankenponResult;
import optimizers.ganeat.jankenpon.ConstantsJankenpon;

public class JankenponMatch implements Callable<Object> {

	public static int bossRatio = 50;

	public static double totalScore = 4000;
	
	private JankenponIndividual indiv1;
	private JankenponIndividual indiv2;
	private int multiplier = 1;

	public JankenponMatch(JankenponIndividual indiv1, JankenponIndividual indiv2){
		this.indiv1 = indiv1;
		this.indiv2 = indiv2;
	}
	
	public JankenponMatch(JankenponIndividual indiv12,
			JankenponIndividual boss, int mult) {
		this(indiv12, boss);
		this.multiplier = mult/JankenponMatch.bossRatio;
	}

	@Override
	public Object call() throws Exception {
		// TODO Auto-generated method stub
		
		JankenponGame result;
		JankenponMatchResult fallouts = new JankenponMatchResult();
		fallouts.mult = this.multiplier;
		if(indiv2 == null){ //if not, lucky, go directly to the next round!
			fallouts.score = multiplier*ConstantsJankenpon.rounds;
			fallouts.winner = indiv1;
			fallouts.oneplayed = new int[]{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
			fallouts.twoplayed = new int[]{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
			fallouts.loser = null;
			//((JankenponResult) indiv1.fitnessResult).addResult(new EloRecord(multiplier*ConstantsJankenpon.rounds,new int[]{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},new int[]{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1},Result.DRAW));
			return fallouts;
		}
		result = indiv1.competeAgainst(indiv2);
		
		if(result.score > ((double)ConstantsJankenpon.rounds)/2.0 || indiv2 == null){
			fallouts.score = multiplier*result.score;
			fallouts.winner = indiv1;
			fallouts.loser = indiv2;
			fallouts.oneplayed = result.iplayed;
			fallouts.twoplayed = result.uplayed;
		} else {
			
		fallouts.winner = indiv2;
		fallouts.loser = indiv1;
		fallouts.oneplayed = result.uplayed;
		fallouts.twoplayed = result.iplayed;
		fallouts.score = multiplier*(ConstantsJankenpon.rounds - result.score);
		}
		
		
		
		return fallouts;
	}
	
	public static void updatePlayers(JankenponMatchResult fallouts){
		JankenponIndividual indiv1, indiv2;
		indiv1 = fallouts.winner;
		indiv2 = fallouts.loser;
		((JankenponResult) indiv1.fitnessResult).addResult(new EloRecord(fallouts.score,fallouts.oneplayed,fallouts.twoplayed,Result.DRAW));
		if(indiv2 != null){
			((JankenponResult) indiv2.fitnessResult).addResult(new EloRecord(fallouts.mult*(ConstantsJankenpon.rounds - fallouts.score/fallouts.mult),fallouts.twoplayed,fallouts.oneplayed,Result.DRAW));
		}
	}

}
